package com.itdaan.portal.business.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.SolrDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import com.itdaan.portal.business.domain.Author;
import com.itdaan.portal.business.domain.Blog;
import com.itdaan.portal.business.domain.Group;
import com.itdaan.portal.business.domain.User;
import com.itdaan.portal.business.service.AuthorService;
import com.itdaan.portal.business.service.BlogService;
import com.itdaan.portal.business.service.GroupService;
import com.itdaan.portal.business.service.UserService;
import com.itdaan.portal.business.solr.ModelUtil;
import com.itdaan.portal.business.solr.Post;
import com.itdaan.portal.business.solr.SolrClient;
import com.itdaan.portal.business.solr.SolrPage;
import com.itdaan.portal.common.exception.ViewException;

/**
 * 主页及主要业务控制
 * @author www.itdaan.com
 */
@Controller
@RequestMapping(value = "/")
@SessionAttributes
public class IndexController {

	private Logger logger = LoggerFactory.getLogger(IndexController.class);
	
	private static List<Group> listGroups = null;
	
	@Resource(name = "groupService")
	private GroupService groupService;
	@Autowired
	private UserService userService;
	@Autowired
	private BlogService blogService;
	@Autowired
	private AuthorService authorService;
	
    @RequestMapping(value = "/index.html")
    public
    ModelAndView index(
            HttpServletRequest request, HttpServletResponse response,
            @RequestParam(value = "page", required = false) Integer page
    ) throws ViewException {
    	ModelAndView modelAndView = new ModelAndView("portal/index");
    	try{
    		//查询总数
    		SolrClient.startServer();
    		long resultCount = SolrClient.queryForCount("*:*");
    		request.getSession().getServletContext().setAttribute("resultCount", resultCount);
    		modelAndView.addObject("resultCount", resultCount);
    		
    		//查询发表博客最多的作者
    		List<Author> authors = authorService.selectAuthorOfMostBlog();
    		modelAndView.addObject("authors", authors);
    		
			//查询最新加入的用户
			List<User> users = userService.getNewestUsers(null);
			modelAndView.addObject("users", users);
			
			//查询最热门的(查看次数最多)
			List<Blog> hostestBlogs = blogService.findHotest();
			modelAndView.addObject("hostestBlogs", hostestBlogs);
			
			//查询收藏数最多的
			List<Blog> collectionMoreBlogs = blogService.findCollectionMore();
			modelAndView.addObject("collectionMoreBlogs", collectionMoreBlogs);
			
			//查询推荐数最多的
			List<Blog> recommendMoreBlogs = blogService.findRecommendMore();
			modelAndView.addObject("recommendMoreBlogs", recommendMoreBlogs);
    	}catch(Exception e){
			logger.error("后台业务逻辑出现异常", e);
    	}
    	return modelAndView;
    }
    
    @RequestMapping(value = "/so", method = RequestMethod.GET)
    public
    ModelAndView list(
            HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam(value = "q", required = false) String q,
            @RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "t", required = false) String type,
            @RequestParam(value = "l", required = false) String languageId,
            @RequestParam(value = "g", required = false) String groupIds
    ) throws ViewException {
    	ModelAndView modelAndView = new ModelAndView("portal/list");
    	try{
    		StringBuffer queryString = new StringBuffer("");
    		if(!StringUtils.isEmpty(q)){
    			q = stringFilter(q);
    			q = ClientUtils.escapeQueryChars(q);
    			queryString.append("title:").append(q);
    		}else{
    			queryString.append("*:").append("*");
    		}
    		if(!StringUtils.isEmpty(type) && !"0".equals(type)){
    			queryString = queryString.append(" AND typeId:").append(type);
    		}
    		if(!StringUtils.isEmpty(languageId) && !"0".equals(languageId)){
    			queryString = queryString.append(" AND languageId:").append(languageId);
    		}
    		if(!StringUtils.isEmpty(groupIds) && !"0".equals(groupIds)){
    			queryString = queryString.append(" AND groupIds:").append(groupIds);
    		}
    		if(StringUtils.isEmpty(type)) type = "0";
    		if(StringUtils.isEmpty(languageId)) languageId = "0";
    		if(StringUtils.isEmpty(groupIds)) groupIds = "0";
			SolrPage solrPage = new SolrPage();
			if(page == null){
				page = 1;
			}else{
				if(page >= 100){
					page = 100;
				}
			}
			solrPage.setCurPage(page);
			Post post = new Post();
			post.setQueryString(queryString.toString());
			SolrClient.startServer();
			QueryResponse solrResponse =  SolrClient.queryForPage(post, solrPage);
			if(!StringUtils.isEmpty(q)){
				q = q.replace("\\", "").replace("-", " ").replace("&", " ");//去掉solr转义的斜线
			}
			List<SolrDocument> list = solrResponse.getResults();
			List<Post> results = new ArrayList<Post>();
			for(SolrDocument solrDocument : list){
				Post domain = new Post();
				for(String name : domain.names){
					ModelUtil.setValue(domain, name, solrDocument.get(name));
				}
				results.add(domain);
			}
			solrPage.setTotalRow(Integer.parseInt(solrResponse.getResults().getNumFound()+""));
			//查询类别
			if(listGroups == null){
				Group group = new Group();
				group.setParentId(0);
				group.setLevel(1);
				listGroups = groupService.findGroupsPage(group);
			}
			Map<String,Long> groupCountMap = new HashMap<String, Long>();
			List<Count> listCounts = solrResponse.getFacetField("groupIds").getValues();
	        for (Count count : listCounts) {
	        	groupCountMap.put(count.getName(), count.getCount());
	        }
	        List<Long> pageIndexs = getPageIndexs(solrPage.getTotalRow(), page);
			modelAndView.addObject("results", results);
			modelAndView.addObject("costTime", solrResponse.getQTime());
			modelAndView.addObject("pageIndexs", pageIndexs);
			modelAndView.addObject("groups", listGroups);
			modelAndView.addObject("groupCountMap", groupCountMap);
			modelAndView.addObject("q",q);
			modelAndView.addObject("t",type);
			modelAndView.addObject("l",languageId);
			modelAndView.addObject("g",groupIds);
			modelAndView.addObject("page",page);
			modelAndView.addObject("totalRow",solrPage.getTotalRow());
    	}catch(Exception e){
			logger.error("后台业务逻辑出现异常", e);
    	}
    	return modelAndView;
    } 
    
    @RequestMapping(value = "/group", method = RequestMethod.GET)
    public
    ModelAndView group(
            HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam(value = "id", required = true) String id,
            @RequestParam(value = "page", required = false) Integer page
    ) throws ViewException {
    	ModelAndView modelAndView = new ModelAndView("portal/group");
    	try{
    		String queryString = "groupIds:".concat(id);
			SolrPage solrPage = new SolrPage();
			if(page == null){
				page = 1;
			}else{
				if(page >= 100){
					page = 100;
				}
			}
			solrPage.setCurPage(page);
			Post post = new Post();
			post.setQueryString(queryString);
			post.setSortField("postTime,id");
			SolrClient.startServer();
			QueryResponse solrResponse =  SolrClient.queryForPage(post, solrPage);
			List<SolrDocument> list = solrResponse.getResults();
			List<Post> results = new ArrayList<Post>();
			for(SolrDocument solrDocument : list){
				Post domain = new Post();
				for(String name : domain.names){
					ModelUtil.setValue(domain, name, solrDocument.get(name));
				}
				results.add(domain);
			}
			solrPage.setTotalRow(Integer.parseInt(solrResponse.getResults().getNumFound()+""));
			String pageHtml = getPageHtml("",null,id,solrPage.getTotalRow(), page,"group");
			//查询类别
			Group group = new Group();
			if(listGroups == null){
				group.setParentId(0);
				group.setLevel(1);
				listGroups = groupService.findGroupsPage(group);
			}
			for(Group g : listGroups){
				if(g.getId().intValue() == Integer.parseInt(id)){
					group = g;
				}
			}				
			Map<String,Long> groupCountMap = SolrClient.queryForGroups();
			modelAndView.addObject("results", results);
			modelAndView.addObject("costTime", solrResponse.getQTime());
			modelAndView.addObject("solrPage", solrPage);
			modelAndView.addObject("pageHtml", pageHtml);
			modelAndView.addObject("groups", listGroups);
			modelAndView.addObject("groupCountMap", groupCountMap);
			modelAndView.addObject("g",group);
    	}catch(Exception e){
			logger.error("后台业务逻辑出现异常", e);
    	}
    	return modelAndView;
    }   
	
    @RequestMapping(value = "/bloglist.html", method = RequestMethod.GET)
    public
    ModelAndView blog(
            HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam(value = "page", required = false) Integer page
    ) throws ViewException {
    	ModelAndView modelAndView = new ModelAndView("portal/blog_list");
    	try{
    		String queryString = "typeId:1";
			SolrPage solrPage = new SolrPage();
			if(page == null){
				page = 1;
			}else{
				if(page >= 100){
					page = 100;
				}
			}
			solrPage.setCurPage(page);
			Post post = new Post();
			post.setQueryString(queryString);
			post.setSortField("postTime,id");
			SolrClient.startServer();
			QueryResponse solrResponse =  SolrClient.queryForPage(post, solrPage);
			List<SolrDocument> list = solrResponse.getResults();
			List<Post> results = new ArrayList<Post>();
			for(SolrDocument solrDocument : list){
				Post domain = new Post();
				for(String name : domain.names){
					ModelUtil.setValue(domain, name, solrDocument.get(name));
				}
				results.add(domain);
			}
			solrPage.setTotalRow(Integer.parseInt(solrResponse.getResults().getNumFound()+""));
			String pageHtml = getPageHtml("",null,null,solrPage.getTotalRow(), page,"blog");
			//查询类别
			Group group = new Group();
			if(listGroups == null){
				group.setParentId(0);
				group.setLevel(1);
				listGroups = groupService.findGroupsPage(group);
			}
			Map<String,Long> groupCountMap = new HashMap<String, Long>();
			List<Count> listCounts = solrResponse.getFacetField("groupIds").getValues();
	        for (Count count : listCounts) {
	        	groupCountMap.put(count.getName(), count.getCount());
	        }			
			modelAndView.addObject("results", results);
			modelAndView.addObject("costTime", solrResponse.getQTime());
			modelAndView.addObject("solrPage", solrPage);
			modelAndView.addObject("pageHtml", pageHtml);
			modelAndView.addObject("groups", listGroups);
			modelAndView.addObject("groupCountMap", groupCountMap);
    	}catch(Exception e){
			logger.error("后台业务逻辑出现异常", e);
    	}
    	return modelAndView;
    }    
    
    @RequestMapping(value = "/faqlist.html", method = RequestMethod.GET)
    public
    ModelAndView faqlist(
            HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam(value = "page", required = false) Integer page
    ) throws ViewException {
    	ModelAndView modelAndView = new ModelAndView("portal/faq_list");
    	try{
    		String queryString = "typeId:2";
			SolrPage solrPage = new SolrPage();
			if(page == null){
				page = 1;
			}else{
				if(page >= 100){
					page = 100;
				}
			}
			solrPage.setCurPage(page);
			Post post = new Post();
			post.setQueryString(queryString);
			post.setSortField("postTime");
			SolrClient.startServer();
			QueryResponse solrResponse =  SolrClient.queryForPage(post, solrPage);
			List<SolrDocument> list = solrResponse.getResults();
			List<Post> results = new ArrayList<Post>();
			for(SolrDocument solrDocument : list){
				Post domain = new Post();
				for(String name : domain.names){
					ModelUtil.setValue(domain, name, solrDocument.get(name));
				}
				results.add(domain);
			}
			solrPage.setTotalRow(Integer.parseInt(solrResponse.getResults().getNumFound()+""));
			String pageHtml = getPageHtml("",null,null,solrPage.getTotalRow(), page,"faq");
			//查询类别
			Group group = new Group();
			if(listGroups == null){
				group.setParentId(0);
				group.setLevel(1);
				listGroups = groupService.findGroupsPage(group);
			}
			Map<String,Long> groupCountMap = new HashMap<String, Long>();
			List<Count> listCounts = solrResponse.getFacetField("groupIds").getValues();
	        for (Count count : listCounts) {
	        	groupCountMap.put(count.getName(), count.getCount());
	        }		
			modelAndView.addObject("results", results);
			modelAndView.addObject("costTime", solrResponse.getQTime());
			modelAndView.addObject("solrPage", solrPage);
			modelAndView.addObject("pageHtml", pageHtml);
			modelAndView.addObject("groups", listGroups);
			modelAndView.addObject("groupCountMap", groupCountMap);
    	}catch(Exception e){
			logger.error("后台业务逻辑出现异常", e);
    	}
    	return modelAndView;
    }    
    
    @RequestMapping(value = "/register.html", method = RequestMethod.GET)
    public
    ModelAndView register(
            HttpServletRequest request,
            HttpServletResponse response
    ) throws ViewException {
    	ModelAndView modelAndView = new ModelAndView("portal/register");
    	return modelAndView;
    }
    
    @RequestMapping(value = "/downcode.html", method = {RequestMethod.GET})
    public
    ModelAndView downcode(
            HttpServletRequest request,
            HttpServletResponse response
    ) throws ViewException {
    	ModelAndView modelAndView = new ModelAndView("portal/downcode");
    	return modelAndView;
    }    
    
    /**
     * 最大支持查询10000页
     * @param totalRow
     * @param curPage
     * @return
     */
	private static List<Long> getPageIndexs(long totalRow,int curPage) {
		if(curPage>=10000) curPage = 10000;//最多支持查看100页
		List<Long> pageIndexs = new ArrayList<Long>();
		long totalPage = (totalRow + 10 - 1) / 10;
		if(totalPage>=10000) totalPage = 10000;
		long startPageIndex = 1;
		long endPageIndex = 1;
		if(curPage < 6){
			startPageIndex = 1;
		}else if(curPage >= 6 && totalPage-curPage > 4){//选择第6页作为当前页
			startPageIndex = curPage - 5;
		}else{
			startPageIndex = totalPage - 9;
			if(startPageIndex < 1) startPageIndex = 1;
		}
		endPageIndex = startPageIndex + 9;
		if(endPageIndex > totalPage) endPageIndex = totalPage;
		for(long i = startPageIndex;i <= endPageIndex;i++){
			pageIndexs.add(i);
		}
		return pageIndexs;
	}    
    
	private static String getPageHtml(String q,String queryInfo,String groupId,long totalRow,int curPage,String type){
		StringBuffer html = new StringBuffer();
		if(curPage > 1){
			if("index".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"index-").append(curPage-1).append(".html\">上一页</a></li>");
			}else if("group".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"group-").append(groupId).append("-").append(curPage-1).append(".html\">上一页</a></li>");
			}else if("blog".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"bloglist-").append(curPage-1).append(".html\">上一页</a></li>");
			}else if("faq".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"faqlist-").append(curPage-1).append(".html\">上一页</a></li>");
			}else{
				if(StringUtils.isEmpty(queryInfo)){
					html.append("<ul><li class=\"prePage\"><a href=\"so-").append(q).append("-").append(curPage-1).append(".html\">上一页</a></li>");
				}else{
					html.append("<ul><li class=\"prePage\"><a href=\"so-").append(q).append("-t-").append(queryInfo.split("#")[0]).append("-l-").append(queryInfo.split("#")[1]).append("-g-").append(queryInfo.split("#")[2]).append("-").append(curPage-1).append(".html\">上一页</a></li>");
				}
			}
		}else{
			if("index".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"index.html\">上一页</a></li>");
			}else if("group".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"group-").append(groupId).append(".html\">上一页</a></li>");
			}else if("blog".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"bloglist.html\">上一页</a></li>");
			}else if("faq".equals(type)){
				html.append("<ul><li class=\"prePage\"><a href=\"faqlist.html\">上一页</a></li>");
			}else{
				if(StringUtils.isEmpty(queryInfo)){
					html.append("<ul><li class=\"prePage\"><a href=\"so-").append(q).append(".html\">上一页</a></li>");
				}else{
					html.append("<ul><li class=\"prePage\"><a href=\"so-").append(q).append("-t-").append(queryInfo.split("#")[0]).append("-l-").append(queryInfo.split("#")[1]).append("-g-").append(queryInfo.split("#")[2]).append(".html\">上一页</a></li>");
				}
			}
		}
		List<Long> pageIndexs = getPageIndexs(totalRow, curPage);
		for(long pageIndex : pageIndexs){
			if(pageIndex == curPage){
				if("index".equals(type)){
					html.append("<li class=\"pageIndex").append(" active\" data=\"").append(pageIndex).append("\"><a href=\"index-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else if("group".equals(type)){
					html.append("<li class=\"pageIndex").append(" active\" data=\"").append(pageIndex).append("\"><a href=\"group-").append(groupId).append("-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else if("blog".equals(type)){
					html.append("<li class=\"pageIndex").append(" active\" data=\"").append(pageIndex).append("\"><a href=\"bloglist-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else if("faq".equals(type)){
					html.append("<li class=\"pageIndex").append(" active\" data=\"").append(pageIndex).append("\"><a href=\"faqlist-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else{
					if(StringUtils.isEmpty(queryInfo)){
						html.append("<li class=\"pageIndex").append(" active\" data=\"").append(pageIndex).append("\"><a href=\"so-").append(q).append("-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
					}else{
						html.append("<li class=\"pageIndex").append(" active\" data=\"").append(pageIndex).append("\"><a href=\"so-").append(q).append("-t-").append(queryInfo.split("#")[0]).append("-l-").append(queryInfo.split("#")[1]).append("-g-").append(queryInfo.split("#")[2]).append("-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
					}
				}
			}else{
				if("index".equals(type)){
					html.append("<li class=\"pageIndex").append("\" data=\"").append(pageIndex).append("\"><a href=\"index-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else if("group".equals(type)){
					html.append("<li class=\"pageIndex").append("\" data=\"").append(pageIndex).append("\"><a href=\"group-").append(groupId).append("-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else if("blog".equals(type)){
					html.append("<li class=\"pageIndex").append("\" data=\"").append(pageIndex).append("\"><a href=\"bloglist-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else if("faq".equals(type)){
					html.append("<li class=\"pageIndex").append("\" data=\"").append(pageIndex).append("\"><a href=\"faqlist-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
				}else{
					if(StringUtils.isEmpty(queryInfo)){
						html.append("<li class=\"pageIndex").append("\" data=\"").append(pageIndex).append("\"><a href=\"so-").append(q).append("-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
					}else{
						html.append("<li class=\"pageIndex").append("\" data=\"").append(pageIndex).append("\"><a href=\"so-").append(q).append("-t-").append(queryInfo.split("#")[0]).append("-l-").append(queryInfo.split("#")[1]).append("-g-").append(queryInfo.split("#")[2]).append("-").append(pageIndex).append(".html\">").append(pageIndex).append("</a></li>");
					}
				}
			}
		}
		long totalPage = (totalRow + 10 - 1) / 10;
		if(curPage == totalPage){
			if("index".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"index-").append(totalPage).append(".html\">下一页</a></li>");
			}else if("group".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"group-").append(groupId).append("-").append(totalPage).append(".html\">下一页</a></li>");
			}else if("blog".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"bloglist-").append(totalPage).append(".html\">下一页</a></li>");
			}else if("faq".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"faqlist-").append(totalPage).append(".html\">下一页</a></li>");
			}else{
				if(StringUtils.isEmpty(queryInfo)){
					html.append("<li class=\"nextPage\"><a href=\"so-").append(q).append("-").append(totalPage).append(".html\">下一页</a></li>");
				}else{
					html.append("<li class=\"nextPage\"><a href=\"so-").append(q).append("-t-").append(queryInfo.split("#")[0]).append("-l-").append(queryInfo.split("#")[1]).append("-g-").append(queryInfo.split("#")[2]).append("-").append(totalPage).append(".html\">下一页</a></li>");
				}
			}
		}else{
			if("index".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"index-").append(curPage+1).append(".html\">下一页</a></li>");
			}else if("group".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"group-").append(groupId).append("-").append(curPage+1).append(".html\">下一页</a></li>");
			}else if("blog".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"bloglist-").append(curPage+1).append(".html\">下一页</a></li>");
			}else if("faq".equals(type)){
				html.append("<li class=\"nextPage\"><a href=\"faqlist-").append(curPage+1).append(".html\">下一页</a></li>");
			}else{
				if(StringUtils.isEmpty(queryInfo)){
					html.append("<li class=\"nextPage\"><a href=\"so-").append(q).append("-").append(curPage+1).append(".html\">下一页</a></li>");
				}else{
					html.append("<li class=\"nextPage\"><a href=\"so-").append(q).append("-t-").append(queryInfo.split("#")[0]).append("-l-").append(queryInfo.split("#")[1]).append("-g-").append(queryInfo.split("#")[2]).append("-").append(curPage+1).append(".html\">下一页</a></li>");
				}
			}
		}
		html.append("</ul>");
		return html.toString();
	}
	
	private String stringFilter(String str){
	  // 清除掉所有特殊字符     
      String regEx = "[`~$%^&*()|{}':;',//[//]<>/?~！%……&*（）——|{}【】‘；：”“’？\"]";
      Pattern p = Pattern.compile(regEx);
      Matcher m = p.matcher(str);
      return m.replaceAll(" ").trim();
	}	
	
}
